

package net.prot;


import java.io.*;
import java.util.*;

/***
 * ***NOTE*** 
 * 
 *     This class and AminoAcidSequence should at some point be
 * merged. The amount of overlap they have is *very* large.
 * 
 */

public class NucleicAcidSequence implements Sequence {

    protected static final Hashtable<Character, String> abrevs;

    protected char[] seq;

    static {
	abrevs = new Hashtable<Character, String>();
	abrevs.put(new Character('G'), "Gua");
	abrevs.put(new Character('A'), "Adn");
	abrevs.put(new Character('T'), "Thy");
	abrevs.put(new Character('C'), "Cyt");
	abrevs.put(new Character('U'), "Urs");
	abrevs.put(new Character(' '), "NUL");
	abrevs.put(new Character('-'), "NUL");
	abrevs.put(new Character('_'), "NUL");
    }

    public NucleicAcidSequence(){
	seq = new char[0];
    }

    public NucleicAcidSequence(char[] seq){
	this.seq = seq;
    }

    public static String lookUpAbrev(char nucleicAcid){
	String abrev = abrevs.get(new Character(nucleicAcid));
	if (abrev != null){
	    return abrev;
	} else {
	    return "UKN";
	}
    }
    
    public static char getComplementAcid(char acid){
	switch (acid){
	    case 'A':
		return 'T';
	    case 'T':
		return 'A';
	    case 'G':
		return 'C';
	    case 'C':
		return 'G';
  	    case 'U':
		return 'A';
	    default:
		return ' ';
	}
    }

    public void setSequenceChars(char[] seq){
	this.seq = seq;
    }

    public char[] getSequenceChars(){
	return seq;
    }

    public void print(){
	print(System.out);
    }

    public void print(PrintStream out){
	out.println(seq);
    }

    public void printAbrev(){
	printAbrev(System.out);
    }

    public void printAbrev(PrintStream out){
	if (seq.length < 1) return;
	out.print(lookUpAbrev(seq[0]));
	for (int i = 1; i < seq.length; i++)
	    out.print("-" + lookUpAbrev(seq[i]));
	out.println();
    }

    public NucleicAcidSequence transcribe(){
	char[] comp = new char[seq.length];
	for (int i = 0; i < seq.length; i++){
	    if (seq[i] != 'A')
		comp[i] = getComplementAcid(seq[i]);
	    else // Deal with the adenisine to ursil during transcription
		comp[i] = 'U';
	}
	return new NucleicAcidSequence(comp);
    }

    public NucleicAcidSequence complementSeq(){
	char[] comp = new char[seq.length];
	for (int i = 0; i < seq.length; i++){
	    comp[i] = getComplementAcid(seq[i]);
	}
	return new NucleicAcidSequence(comp);
    }

    public AminoAcidSequence translate(){
	return null;
    }

    public void shiftRight(int index, int spaces){
	if (index >= seq.length) 
	    throw new IndexOutOfBoundsException("Bad index");
	char[] newArray = new char[seq.length + spaces];
	for (int i = 0; i < index; i++){
	    newArray[i] = seq[i];
	}
	for (int i = 0; i < spaces; i++){
	    newArray[index+i] = ' ';
	}
	for (int i = index+spaces; i < newArray.length; i++){
	    newArray[i] = seq[i-spaces];
	}
	seq = newArray;
    }

    public void shiftLeft(int index, int spaces){
	if (index >= seq.length) 
	    throw new IndexOutOfBoundsException("Bad index");
	char[] newArray = new char[seq.length - spaces];
	for (int i = 0; i < index-spaces; i++){
	    newArray[i] = seq[i];
	}
	for (int i = index-spaces; i < newArray.length; i++){
	    newArray[i] = seq[i+spaces];
	}
	seq = newArray;
    }

    public void insertAcid(int index, char acid){
	shiftRight(index, 1);
	seq[index] = acid;
    }

    public void deleteAcid(int index){
	shiftLeft(index+1, 1);
    }

    public void replaceAcid(int index, char acid){
	seq[index] = acid;
    }

}
